#include "Instance.h"
#include "scene.h"
#include "pSystem.h"
#include "pSystemManager.h"

#define BALA 1
#define LASER 2
#define PLASMA 3

Instance::Instance() 
{
	target = -1;
	speed = 0.0f;
	model = new Matrix44();
	model->setIdentity();
	//position = new Vector3();
	shader = NULL;
	
}
Instance::~Instance()
{

}
Instance::Instance(std::string _id_mesh, std::string _id_controller, Vector3 _position, Matrix44 * _model)
{
	speed = -1.0f;
	id_instance = Scene::instances_layer1.size(); //getTime();
	id_mesh = _id_mesh;
	id_controller = _id_controller;
	position = _position;
	model = _model;
	model->traslate(_position.x,_position.y,_position.z);
	shader = NULL;
	isPlayer = false;
	timeActions.push_back(getTime());
	timeActions.push_back(getTime());
	
}

Instance::Instance(std::string _id_mesh, std::string _id_controller, Vector3 _position, Matrix44 * _model, std::string _shader)
{
	speed = -1.0f;
	id_instance = Scene::instances_layer1.size(); //getTime();
	id_mesh = _id_mesh;
	id_controller = _id_controller;
	position = _position;
	model = _model;
	model->traslate(_position.x,_position.y,_position.z);
	shader = NULL;
	isPlayer = false;
	timeActions.push_back(getTime());
	timeActions.push_back(getTime());
}

void Instance::setShader(std::string _shader)
{
	//Create a shader from two files


	if(_shader == "phong")
	{
		shader = new Shader();
		shader=Shader::Load("shaders/phong.vs","shaders/phong.ps"); //this renders using a simplified goureud equation	
	}
	if(_shader == "gouraud")
	{
		shader = new Shader();
		shader=Shader::Load("shaders/gouraud.vs","shaders/gouraud.ps");//this renders using a simplified goureud equation	}
	}
	if(_shader == "simple")
	{
		shader = new Shader();
		shader=Shader::Load("shaders/simple.vs","shaders/simple.ps"); //this renders using a simplified goureud equation
	}
	if(_shader == "shader")
	{
		shader = new Shader();
		shader=Shader::Load("shaders/shader.vs","shaders/shader.ps"); //this renders using a simplified goureud equation
	}
}

//=============================================================================================================
//=============================================================================================================
//=============================================================================================================

Ship::~Ship(){
	
}

Ship::Ship(std::string _id_mesh, std::string _id_controller, Vector3 _position, Matrix44 * _model,std::string _tipo_nave, std::string _shader, std::string _team)
{
	enginePS * eps;
	shipColor = Vector3(1.0,1.0,1.0);
	if(_team == "red") shipColor = Vector3(1.0,0.1,0.1);
	if(_team == "blue") shipColor = Vector3(0.1,0.1,1.1);
	if(_team == "green") shipColor = Vector3(0.1,1.1,0.1);
	
	setTag("tipo",_tipo_nave);
	alive = true;
	speed = -0.0f;
	id_instance = Scene::instances_layer1.size();
	id_mesh = _id_mesh;
	id_controller = _id_controller;
	position = _position;
	velocidad.set(0,0,0);
	model = _model;
	model->traslate(_position.x,_position.y,_position.z);
	shader = NULL;
	isPlayer = false;
	lastFire.push_back(getTime());
	lastFire.push_back(getTime());
	lastFire.push_back(getTime());
	lastRegeneration.push_back(getTime());
	lastRegeneration.push_back(getTime());
	vision = 3000;
	if (_shader != ""){
		setShader(_shader);
	}
	if(_team != "") setTag("team",_team);
	
	controller = NULL;
	if(_id_controller == "equipos"){
		controller = new controllerPerseguirEquipo();
		controller->owner = id_instance;
	} else if (_id_controller == "equipos_pred"){
		controller = new controllerPerseguirEquipoPred();
		controller->owner = id_instance;
	}
	timeActions.push_back(getTime());
	timeActions.push_back(getTime());
	std::vector<pSystem*> engines;
	if( _tipo_nave == "x3_fighter"){
			life = 100;
			speed_max = 100;
			v_ang = 70;
			shield = 100;
			offset = Vector3(0,0,18);
			eps = new enginePS();
			eps->create(20,this,Vector3(0,0,8.1),2);
			engines.push_back(eps);
			//pSystemManager::addPSystem(eps);
	}
	else if( _tipo_nave == "x3_runner"){
			life = 250;
			speed_max = 120;
			v_ang = 100;
			shield = 70;
			life_max = life;
			shield_max = shield;
			offset = Vector3(0,-10,13);
			//sistema particulas motor 1
			eps = new enginePS();
			eps->create(20,this,Vector3(0,3.5,14.6),3);
			engines.push_back(eps);
			//pSystemManager::addPSystem(eps);
			//sistema particulas motor 2
			eps = new enginePS();
			eps->create(20,this,Vector3(+0.9,0.8,14.6),3);
			engines.push_back(eps);
			//pSystemManager::addPSystem(eps);
			//sistema particulas motor 3
			eps = new enginePS();
			eps->create(20,this,Vector3(-0.9,0.8,14.6),3);
			engines.push_back(eps);
			//pSystemManager::addPSystem(eps);
	}
	else if( _tipo_nave == "tank"){
			life = 2000;
			speed_max = 50;
			v_ang = 150;
			shield = 1000;
			life_max = life;
			shield_max = shield;
			offset = Vector3(0,0,100);
	}
	else if( _tipo_nave == "station"){
			life = 5000;
			speed_max = 100;
			v_ang =300;
			shield = 2000;
			life_max = life;
			shield_max = shield;
			offset = Vector3(0,0,200);
	}
	else if( _tipo_nave == "space_train"){
			life = 5000;
			speed_max = 100;
			v_ang = 300;
			shield = 2000;
			offset = Vector3(0,-50,180);
			life_max = life;
			shield_max = shield;

			eps = new enginePS();
			eps->create(20,this,Vector3(0,-50,179),15);
			engines.push_back(eps);

			eps = new enginePS();
			eps->create(20,this,Vector3(-15,-34,162),7);
			engines.push_back(eps);

			eps = new enginePS();
			eps->create(20,this,Vector3(15,-34,162),7);
			engines.push_back(eps);
			//pSystemManager::addPSystem(eps);
	}
	
	else if( _tipo_nave == "fragate"){
			life = 4000;
			speed_max = 100;
			v_ang = 400;
			shield = 1500;
			life_max = life;
			shield_max = shield;
			offset = Vector3(0,0,150);
			
	}
	else{
			life = 200;
			speed_max = 100;
			v_ang = 100;
			shield = 100;
			life_max = life;
			shield_max = shield;
			offset = Vector3(0,0,20);
	}
	life_max = life;
	shield_max = shield;
	pSystemManager * SM = pSystemManager::getPSManager();
	for (int i = 0; i < engines.size(); i++){
		SM->addPSystem(engines[i]);
	}
}

void Ship::setTag(std::string _tag, std::string _value)
{
	std::map<std::string,std::string>::iterator it = tags.find(_tag);
	if(it == tags.end()){
		tags.insert(std::pair<std::string,std::string> (_tag,_value));
	}
	else{
		tags[_tag] = _value;
	}
}

std::string Ship::getTag(std::string _tag)
{
	std::map<std::string,std::string>::iterator it = tags.find(_tag);
	if(it != tags.end()){
		return it->second;
	}
	return "";
}

void Ship::processMessage(std::string _message)
{
	size_t pos;
	pos = _message.find("|");
	if (pos != std::string::npos){
		std::string directive = _message.substr(0,pos);
		std::string what = _message.substr(pos+1,_message.length());
		if( directive == "hurt"){
			double damage = strtod(what.data(),NULL);
			if( this->shield > 0.0 ) this->shield -= damage;
			else this->life -= damage;
			if(this->life <= 0.0){
				this->life = 0;
				//nave muerta, explosion y borrar
				std::cout << "NAVE MUERTA"<<std::endl;
				alive = false;
			}
		}
		if (directive == "regenerate"){
			if(what == "shield" && (getTime() - lastRegeneration[0] > 500)){
				lastRegeneration[0]=(getTime());
				if(isPlayer) shield += 10;
				else shield ++;
				if (shield >= shield_max) shield = shield_max;
			}
		}
	}
}

void Ship::Move(std::string _action, double _value, double _seconds_elapsed){
	/*
		Actions
		right
		left
		up
		down
		roll_right
		roll_left
		accelerate
		break
		value = percentage
	*/

	if (Scene::getScene()->estado_juego != EST_JUEGO) return;
	double mov = 1.0;
	mov *= (_value/100);
	double now = getTime();
	float vel_angular = ((_value/100) * _seconds_elapsed * 100)/(v_ang);

	float actual_speed = _seconds_elapsed * (speed * speed_max) * 2.0;// * 200.0;//speed_max * (speed) * _seconds_elapsed * 200;
	
	if (abs(actual_speed) > 0){
		actual_speed = actual_speed;
		//std::cout <<"Instance - "<<id_mesh<<" || Speed = " << actual_speed << std::endl;
	}
	if(_value > 100) _value = 100;
	if (_value > 0){
		if (_action == "forward"){
			if(timerRebote == 0)
 				model->traslateLocal(0.0f,0.0f,actual_speed*(_value/100));
		}
		else if(_action == "right"){
			model->rotateLocal(vel_angular,Vector3(0,mov,0));
		}
		else if (_action == "left"){
			model->rotateLocal(vel_angular,Vector3(0,-mov,0));
		}
		else if (_action == "up"){
			model->rotateLocal(vel_angular,Vector3(-mov,0,0));
		}
		else if (_action == "down"){
			model->rotateLocal(vel_angular,Vector3(mov,0,0));
		}
		else if (_action == "roll_right"){
			model->rotateLocal(vel_angular,Vector3(0,0,mov));
		}
		else if (_action == "roll_left"){
			model->rotateLocal(vel_angular,Vector3(0,0,-mov));
		}
		else if (_action == "accelerate"){
			if (now - timeActions[0] < 100){
				return;
			}
			timeActions[0] = now;
			if (speed > -1.0) this->speed = speed - 0.05;
		}
		else if (_action == "break"){
			if (now - timeActions[1] < 100){
				return;
			}
			timeActions[1] = now;
			if (speed < 0.5) this->speed = speed + 0.05;
		}
		else if(_action == "rebote"){
			float modulo = _seconds_elapsed*20;
			rebote.normalize();
			Vector3 front = Vector3(0,0,1);
			model->traslateLocal(front.x*modulo,front.y*modulo,front.z*modulo);
		}
	}
	velocidad = model->frontVector().normalize() * actual_speed *(_value/100);
}
